package com.cts.learninglibrary.service.impl;

import com.cts.learninglibrary.dto.LoginDto;
import com.cts.learninglibrary.exception.LoginErrorException;
import com.cts.learninglibrary.pojo.User;
import com.cts.learninglibrary.service.LoginService;
import com.cts.learninglibrary.service.UserService;
import com.cts.learninglibrary.util.CommonConverterUtil;
import com.cts.learninglibrary.util.R;
import com.cts.learninglibrary.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author arctique
 * @date 2020/8/24 13:13
 */
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    private final String SESSION_KEY = "SESSION_KEY:";

    @Autowired
    private UserService userService;
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 登录
     *
     * @param username
     * @param password
     * @return
     */
    @Override
    public R login(String username, String password) {
        LoginDto loginDto = null;
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password);
        subject.login(usernamePasswordToken);
        if (subject.isAuthenticated()) {
            User user = userService.findByUsername(username);
            loginDto = CommonConverterUtil.convert(user, LoginDto.class);

            // 设置返回token
            String token = subject.getSession().getId().toString();
            loginDto.setToken(token);

            // 将token写进redis
            redisUtil.set(SESSION_KEY + loginDto.getUsername(), token);
            redisUtil.expire(SESSION_KEY + loginDto.getUsername(), 3600L);
        }
        return loginDto != null ? R.failed(loginDto, "登录成功") : R.failed("登录失败");
    }

    /**
     * 登出
     *
     * @return
     */
    @Override
    public R logout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.getPrincipal() == null) {
            throw new LoginErrorException(-1, "请先登录");
        }
        Object object = subject.getPrincipal();
        User user = CommonConverterUtil.convert(object, User.class);
        String username = user.getUsername();
        subject.logout();
        log.info("{}-[登出成功]", username);
        redisUtil.del(SESSION_KEY + username);
        System.out.println("是否存在redis-key：" + redisUtil.hasKey(SESSION_KEY + username));
        return redisUtil.hasKey(SESSION_KEY + username) ? R.failed("登出失败") : R.ok("登出成功");
    }
}
